home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / raid / devRaidReconstruct.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-09  |  9.1 KB  |  311 lines

  1. /* 
  2.  * devRaidInitiate.c --
  3.  *
  4.  *    This file implements the BlockDevice interface for homogeneous disk
  5.  *    arrays.
  6.  *
  7.  * Copyright 1989 Regents of the University of California
  8.  * All rights reserved.
  9.  * Permission to use, copy, modify, and distribute this
  10.  * software and its documentation for any purpose and without
  11.  * fee is hereby granted, provided that the above copyright
  12.  * notice appear in all copies.  The University of California
  13.  * makes no representations about the suitability of this
  14.  * software for any purpose.  It is provided "as is" without
  15.  * express or implied warranty.
  16.  */
  17.  
  18. #include "sync.h"
  19. #include <string.h>
  20. #include <stdio.h>
  21. #include "sprite.h"
  22. #include "fs.h"
  23. #include "dev.h"
  24. #include "devBlockDevice.h"
  25. #include "devRaid.h"
  26. #include "semaphore.h"
  27. #include "stdlib.h"
  28. #include "devRaidUtil.h"
  29. #include "schedule.h"
  30. #include "devRaidProto.h"
  31.  
  32.  
  33. /*
  34.  *----------------------------------------------------------------------
  35.  *
  36.  * Raid_InitiateReconstruction --
  37.  *
  38.  *    Reconstruct the contents of the failed disk.
  39.  *    System must be quiesced
  40.  *
  41.  * Results:
  42.  *    None.
  43.  *
  44.  * Side effects:
  45.  *    Reconstructs the contents of the failed disk.
  46.  *
  47.  *----------------------------------------------------------------------
  48.  */
  49.  
  50. static void InitiateStripeReconstruction();
  51.  
  52. void
  53. Raid_InitiateReconstruction(raidPtr, col, row, version, numSector, uSec, doneProc,
  54.     clientData, ctrlData)
  55.     Raid    *raidPtr;
  56.     int         col, row, version;
  57.     int         numSector;
  58.     int         uSec;
  59.     void       (*doneProc)();
  60.     ClientData   clientData;
  61.     int         ctrlData;
  62. {
  63.     RaidReconstructionControl    *reconstructionControlPtr;
  64.     RaidDisk            *diskPtr;
  65.  
  66.     LockSema(&raidPtr->disk[col][row]->lock);
  67.     diskPtr = raidPtr->disk[col][row];
  68.     if (version != diskPtr->version || diskPtr->state != RAID_DISK_READY) {
  69.     UnlockSema(&diskPtr->lock);
  70.     return;
  71.     }
  72.     UnlockSema(&diskPtr->lock);
  73.     reconstructionControlPtr = Raid_MakeReconstructionControl(raidPtr,
  74.         col, row, diskPtr, doneProc, clientData, ctrlData);
  75.     InitiateStripeReconstruction(reconstructionControlPtr);
  76. }
  77.  
  78.  
  79. /*
  80.  *----------------------------------------------------------------------
  81.  *
  82.  * reconstructionDoneProc --
  83.  *
  84.  *    Callback procedure for Raid_InitiateReconstruction.
  85.  *
  86.  * Results:
  87.  *    None.
  88.  *
  89.  * Side effects:
  90.  *    None.
  91.  *
  92.  *----------------------------------------------------------------------
  93.  */
  94.  
  95. static void
  96. reconstructionDoneProc(reconstructionControlPtr)
  97.     RaidReconstructionControl    *reconstructionControlPtr;
  98. {
  99.     reconstructionControlPtr->doneProc(reconstructionControlPtr->clientData,
  100.             reconstructionControlPtr->status);
  101.     Raid_FreeReconstructionControl(reconstructionControlPtr);
  102. }
  103.  
  104.  
  105. /*
  106.  *----------------------------------------------------------------------
  107.  *
  108.  * Raid_InitiateReconstructionFailure --
  109.  *
  110.  *    Causes the reconstruction to fail.
  111.  *
  112.  * Results:
  113.  *    None.
  114.  *
  115.  * Side effects:
  116.  *    None.
  117.  *
  118.  *----------------------------------------------------------------------
  119.  */
  120.  
  121. static void
  122. Raid_InitiateReconstructionFailure(reconstructionControlPtr)
  123.     RaidReconstructionControl    *reconstructionControlPtr;
  124. {
  125.     int             stripeID = reconstructionControlPtr->stripeID;
  126.  
  127.     Raid_XUnlockStripe(reconstructionControlPtr->raidPtr, stripeID);
  128.     Raid_ReportReconstructionFailure(reconstructionControlPtr->col,
  129.             reconstructionControlPtr->row);
  130.     reconstructionControlPtr->status = FAILURE;
  131.     reconstructionDoneProc(reconstructionControlPtr);
  132. }
  133.  
  134.  
  135. /*
  136.  *----------------------------------------------------------------------
  137.  *
  138.  * InitiateStripeReconstruction --
  139.  *
  140.  *    Reconstructs a single stripe.
  141.  *
  142.  * Results:
  143.  *    None.
  144.  *
  145.  * Side effects:
  146.  *    None.
  147.  *
  148.  *----------------------------------------------------------------------
  149.  */
  150.  
  151. static void reconstructionReadDoneProc();
  152. static void reconstructionWriteDoneProc();
  153.  
  154. static void
  155. InitiateStripeReconstruction(reconstructionControlPtr)
  156.     RaidReconstructionControl    *reconstructionControlPtr;
  157. {
  158.     Raid           *raidPtr       = reconstructionControlPtr->raidPtr;
  159.     int                col           = reconstructionControlPtr->col;
  160.     int                row           = reconstructionControlPtr->row;
  161.     RaidDisk           *diskPtr       = reconstructionControlPtr->diskPtr;
  162.     int                   ctrlData      = reconstructionControlPtr->ctrlData;
  163.     RaidRequestControl *reqControlPtr = reconstructionControlPtr->reqControlPtr;
  164.     char           *readBuf       = reconstructionControlPtr->readBuf;
  165.     char           *parityBuf     = reconstructionControlPtr->parityBuf;
  166.     int                stripeID;
  167.     unsigned            firstSector;
  168.     unsigned            nthSector;
  169.  
  170.     LockSema(&diskPtr->lock);
  171.     if (diskPtr->numValidSector == raidPtr->sectorsPerDisk) {
  172.         printf("RAID:MSG:Reconstruction completed.\n");
  173.     reconstructionDoneProc(reconstructionControlPtr);
  174.     UnlockSema(&diskPtr->lock);
  175.     return;
  176.     }
  177.     if (diskPtr->state != RAID_DISK_READY) {
  178.         printf("RAID:MSG:Reconctruction aborted.\n");
  179.     reconstructionDoneProc(reconstructionControlPtr);
  180.     UnlockSema(&diskPtr->lock);
  181.     return;
  182.     }
  183.     Raid_MapPhysicalToStripeID(raidPtr, col,row, diskPtr->numValidSector, &stripeID);
  184.     Raid_XLockStripe(raidPtr, stripeID);
  185.     UnlockSema(&diskPtr->lock);
  186.     reconstructionControlPtr->stripeID = stripeID;
  187.     firstSector = StripeIDToSector(raidPtr, stripeID);
  188.     nthSector   = NthSectorOfStripe(raidPtr, firstSector);
  189.     reqControlPtr->numReq = reqControlPtr->numFailed = 0;
  190.     AddRaidDataRequests(reqControlPtr, raidPtr, FS_READ,
  191.         firstSector, nthSector, readBuf, ctrlData);
  192.     AddRaidParityRequest(reqControlPtr, raidPtr, FS_READ,
  193.         firstSector, parityBuf, ctrlData);
  194.     if (reqControlPtr->numFailed == 1) {
  195.     Raid_InitiateIORequests(reqControlPtr,
  196.         reconstructionReadDoneProc,
  197.         (ClientData) reconstructionControlPtr);
  198.     } else {
  199.     Raid_InitiateReconstructionFailure(reconstructionControlPtr);
  200.     }
  201. }
  202.  
  203.  
  204. /*
  205.  *----------------------------------------------------------------------
  206.  *
  207.  * reconstructionReadDoneProc --
  208.  *
  209.  *    Callback procedure for InitiateStripeReconstruction.
  210.  *
  211.  * Results:
  212.  *    None.
  213.  *
  214.  * Side effects:
  215.  *    Computes and writes the reconstructed information.
  216.  *
  217.  *----------------------------------------------------------------------
  218.  */
  219.  
  220. static void
  221. reconstructionReadDoneProc(reconstructionControlPtr, numFailed)
  222.     RaidReconstructionControl    *reconstructionControlPtr;
  223.     int                  numFailed;
  224. {
  225.     Raid           *raidPtr       = reconstructionControlPtr->raidPtr;
  226.     RaidDisk           *diskPtr       = reconstructionControlPtr->diskPtr;
  227.     RaidRequestControl *reqControlPtr = reconstructionControlPtr->reqControlPtr;
  228.     RaidBlockRequest   *failedReqPtr  =
  229.                       reconstructionControlPtr->reqControlPtr->failedReqPtr;
  230.  
  231.     if (numFailed > 0) {
  232.     Raid_InitiateReconstructionFailure(reconstructionControlPtr);
  233.     } else {
  234. #ifndef NODATA
  235.     bzero(failedReqPtr->devReq.buffer, failedReqPtr->devReq.bufferLen);
  236. #endif
  237.     Raid_XorRangeRequests(reqControlPtr, raidPtr,
  238.         failedReqPtr->devReq.buffer,
  239.         (int) failedReqPtr->devReq.startAddress,
  240.         failedReqPtr->devReq.bufferLen);
  241.     reqControlPtr->failedReqPtr->devReq.operation = FS_WRITE;
  242.     reqControlPtr->failedReqPtr->state = REQ_READY;
  243.     LockSema(&diskPtr->lock);
  244.     if (diskPtr->state != RAID_DISK_READY) {
  245.         printf("RAID:MSG:Reconctruction aborted.\n");
  246.         Raid_InitiateReconstructionFailure(reconstructionControlPtr);
  247.         UnlockSema(&diskPtr->lock);
  248.         return;
  249.     }
  250.     diskPtr->numValidSector =
  251.         NthSectorOfStripeUnit(raidPtr, diskPtr->numValidSector);
  252.     UnlockSema(&diskPtr->lock);
  253.     Raid_InitiateIORequests(reqControlPtr, reconstructionWriteDoneProc,
  254.         (ClientData) reconstructionControlPtr);
  255.     }
  256. }
  257.  
  258.  
  259. /*
  260.  *----------------------------------------------------------------------
  261.  *
  262.  * reconstructionWriteDoneProc --
  263.  *
  264.  *    Callback procedure for reconstructionReadDoneProc.
  265.  *
  266.  * Results:
  267.  *    None.
  268.  *
  269.  * Side effects:
  270.  *    Initiates the reconstruction of the next sector on the failed device.
  271.  *
  272.  *----------------------------------------------------------------------
  273.  */
  274.  
  275. static void
  276. reconstructionWriteDoneProc(reconstructionControlPtr, numFailed)
  277.     RaidReconstructionControl    *reconstructionControlPtr;
  278.     int                 numFailed;
  279. {
  280.     Raid           *raidPtr       = reconstructionControlPtr->raidPtr;
  281.     RaidDisk           *diskPtr       = reconstructionControlPtr->diskPtr;
  282.     int                stripeID      = reconstructionControlPtr->stripeID;
  283.  
  284.     if (numFailed > 0) {
  285.     LockSema(&diskPtr->lock);
  286.     if (diskPtr->state != RAID_DISK_READY) {
  287.         printf("RAID:MSG:Reconctruction aborted.\n");
  288.         Raid_InitiateReconstructionFailure(reconstructionControlPtr);
  289.         UnlockSema(&diskPtr->lock);
  290.         return;
  291.     }
  292.     diskPtr->numValidSector =
  293.         FirstSectorOfStripeUnit(raidPtr, diskPtr->numValidSector);
  294.     UnlockSema(&diskPtr->lock);
  295.     Raid_InitiateReconstructionFailure(reconstructionControlPtr);
  296.     } else {
  297.     LockSema(&diskPtr->lock);
  298.     if (diskPtr->state == RAID_DISK_READY) {
  299.         printf("RAID:RECON:%d %d %d\n",
  300.             diskPtr->device.type, diskPtr->device.unit,
  301.             SectorToStripeUnitID(raidPtr, diskPtr->numValidSector-1));
  302.         Raid_SaveDiskState(raidPtr, diskPtr->col, diskPtr->row,
  303.             diskPtr->device.type, diskPtr->device.unit,
  304.             diskPtr->version, diskPtr->numValidSector);
  305.     }
  306.     UnlockSema(&diskPtr->lock);
  307.     Raid_XUnlockStripe(raidPtr, stripeID);
  308.     InitiateStripeReconstruction(reconstructionControlPtr);
  309.     }
  310. }
  311.